package com.acmedcare.framework.exchange.center.endpoint.service;

import com.acmedcare.framework.boot.snowflake.Snowflake;
import com.acmedcare.framework.exchange.center.common.ConvertUtils;
import com.acmedcare.framework.exchange.center.common.Page;
import com.acmedcare.framework.exchange.center.endpoint.exception.InvalidRequestParameterException;
import com.acmedcare.framework.exchange.center.entity.bean.Task;
import com.acmedcare.framework.exchange.center.entity.dto.CommandEvent;
import com.acmedcare.framework.exchange.center.entity.dto.TaskActionDto;
import com.acmedcare.framework.exchange.center.entity.dto.TaskListQueryDto;
import com.acmedcare.framework.exchange.center.entity.dto.TaskListViewDto;
import com.acmedcare.framework.exchange.center.entity.dto.TaskStatusEnum;
import com.acmedcare.framework.exchange.center.repository.PluginRepository;
import com.acmedcare.framework.exchange.center.repository.TaskRepository;
import com.acmedcare.framework.starter.bus.AcmedcareEventPublisher;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Service
public class TaskService {

  private final TaskRepository taskRepository;
  private final AcmedcareEventPublisher publisher;
  private final Snowflake snowflake;
  final PluginRepository pluginRepository;

  public TaskService(TaskRepository taskRepository,
      AcmedcareEventPublisher publisher, Snowflake snowflake,
      PluginRepository pluginRepository) {
    this.taskRepository = taskRepository;
    this.publisher = publisher;
    this.snowflake = snowflake;
    this.pluginRepository = pluginRepository;
  }

  private static TaskListViewDto apply(Task task) {
    TaskListViewDto viewDto;
    viewDto = ConvertUtils.convertType(task, TaskListViewDto.class);
    return viewDto;
  }

  public Page<TaskListViewDto> getList(TaskListQueryDto queryDto) {

    QueryWrapper<Task> queryWrapper = new QueryWrapper<>();
    if (!StringUtils.isEmpty(queryDto.getName())) {

      queryWrapper.like("name", queryDto.getName());
    }

    if (queryDto.getBeginTime() != null) {

      queryWrapper.gt("create_time", queryDto.getBeginTime());
    }

    if (queryDto.getEndTime() != null) {

      queryWrapper.lt("create_time", queryDto.getEndTime());
    }

    if (queryDto.getStatus() != null) {

      queryWrapper.eq("status", queryDto.getStatus().toString());
    }

    queryWrapper.orderByDesc("create_time");

    PageHelper.startPage(queryDto.getCurrPage(), queryDto.getSize());
    List<Task> tasks = taskRepository.selectList(queryWrapper);
    if (!tasks.isEmpty()) {

      Page<Task> taskPage = ConvertUtils.convertPage(tasks);
      List<TaskListViewDto> viewDtoList = taskPage.getList().stream().map(TaskService::apply).collect(Collectors.toList());
      Page<TaskListViewDto> viewDtoPage = ConvertUtils.convertPage(viewDtoList);
      viewDtoPage.setRowCount(taskPage.getRowCount());
      viewDtoPage.setSize(taskPage.getSize());
      viewDtoPage.setNum(taskPage.getNum());
      viewDtoPage.setPageCount(taskPage.getPageCount());
      return viewDtoPage;
    }

    return null;
  }

  public Task getDetail(Long taskId) {

    return taskRepository.selectById(taskId);
  }

  public Long createTask(TaskActionDto actionDto) throws InvalidRequestParameterException {

    Task task = getTaskByName(actionDto.getName());
    if (task != null) {
      throw new InvalidRequestParameterException("任务名称已存在，不允许再次添加!");
    }

    task = new Task();
    task.setStatus(TaskStatusEnum.STOPED);
    task = ConvertUtils.convertType(actionDto, Task.class);
    task.setTaskId(snowflake.nextId());
    taskRepository.insert(task);
    return task.getTaskId();
  }

  public void update(TaskActionDto actionDto, Long taskId) throws InvalidRequestParameterException {

    Task task = getTaskByName(actionDto.getName());
    if (task != null && !task.getTaskId().equals(taskId)) {
      throw new InvalidRequestParameterException("任务名称已存在，不允许再次添加!");
    }

    task = taskRepository.selectById(taskId);

    if (!task.getName().equals(actionDto.getName())) {

      CommandEvent commandEvent = new CommandEvent();
      commandEvent.setCommandType(TaskStatusEnum.STOP);
      commandEvent.setTask(task);

      String workerName = "exchange-center-executor";
      if (!org.apache.commons.lang.StringUtils.isEmpty(task.getGroupName())) {

        workerName = String.format("%s-exchange-center-executor", task.getGroupName());
      }

      publisher.publishEvent(workerName, commandEvent);
    }

    task = ConvertUtils.convertType(actionDto, Task.class);
    task.setTaskId(taskId);
    taskRepository.updateById(task);
  }

  private Task getTaskByName(String name) {

    QueryWrapper<Task> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("name", name);

    return taskRepository.selectOne(queryWrapper);
  }
}